package com.qixiaobao.common.utils.pdf;


import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import com.qixiaobao.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * @ClassName PdfWaterUtils
 * @Author yangxm
 * @Description pdf添加水印工具类
 * @Date 2023/5/11 5:06 PM
 */
@Slf4j
public class PdfWaterUtils {

    /** 水印文字 */
    private static final String WATER = "QXBINS";

    /** 每页需要插入的水印条数 */
    private static final int NUM = 3;

    /**
     * pdf生成水印
     *
     * @param inputStream       插入前的文件流
     * @param tarPdfPath       插入后的文件路径
     * @param waterMarkContent 水印文案
     * @param numberOfPage     每页需要插入的条数
     * @throws Exception
     */
    public static void addWaterMark(InputStream inputStream, String tarPdfPath, String waterMarkContent, Integer numberOfPage) throws Exception {
        if (StringUtils.isBlank(waterMarkContent)){
            waterMarkContent =  WATER;
        }
        if (numberOfPage == null){
            numberOfPage = NUM;
        }
        //创建文件路径
        createFilePath(tarPdfPath);
        PdfReader reader = new PdfReader(inputStream);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tarPdfPath));
        //设置权限
        stamper.setEncryption(null, null, PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);

        PdfGState gs = new PdfGState();
        //设置字体（支持中文）
        //BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        //微软雅黑字体
        String fontPath = "src/main/resources/font/MSYH.TTC,0";
        BaseFont font = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED );

        // 设置透明度
        gs.setFillOpacity(0.05f);

        int total = reader.getNumberOfPages() + 1;
        PdfContentByte content;
        for (int i = 1; i < total; i++) {
            content = stamper.getOverContent(i);
            content.beginText();
            content.setGState(gs);
            //水印颜色
            content.setColorFill(BaseColor.DARK_GRAY);
            //水印字体样式和大小
            content.setFontAndSize(font, 60);

            //插入水印  循环每页插入的条数
            for (int j = 0; j < numberOfPage; j++) {
                content.showTextAligned(Element.ALIGN_CENTER, waterMarkContent, 300, 200 * (j + 1), 30);
            }
            content.endText();
        }
        stamper.close();
        reader.close();
        //boolean b = deleteFile(srcPdfPath);
        System.out.println("PDF水印添加完成！");
    }

    /**
     * @Description 将pdf另存为图像pdf，解决图层问题
     * @Author yangxm
     * @Date 2025/4/14 9:40
     * @param srcPdfPath
     * @param tarPdfPath
     */
    public static void saveAsImgPdf(String srcPdfPath, String tarPdfPath) throws Exception {
        //创建文件路径
        createFilePath(tarPdfPath);
        try (PDDocument document = PDDocument.load(Files.newInputStream(Paths.get(srcPdfPath)));
             PDDocument newDocument = new PDDocument()) {

            PDFRenderer pdfRenderer = new PDFRenderer(document);
            int pageCount = document.getNumberOfPages();

            File tempFile;
            BufferedImage bim;
            PDPage newPage;
            PDImageXObject pdImage;

            for (int page = 0; page < pageCount; ++page) {
                // 将PDF页面渲染为BufferedImage
                bim = pdfRenderer.renderImageWithDPI(page, 300); // 300 DPI

                // 创建临时文件
                tempFile = File.createTempFile("temp", ".png");
                ImageIO.write(bim, "png", tempFile);

                // 创建一个新的PDF页面
                newPage = new PDPage();
                newDocument.addPage(newPage);

                // 将BufferedImage转换为PDImageXObject
                pdImage = PDImageXObject.createFromFile(tempFile.getAbsolutePath(), newDocument);
                // 在新页面上绘制图像
                try (PDPageContentStream contentStream = new PDPageContentStream(newDocument, newPage)) {
                    contentStream.drawImage(pdImage, 0, 0, newPage.getMediaBox().getWidth(), newPage.getMediaBox().getHeight());
                }
                // 删除临时文件
                tempFile.delete();
            }
            // 保存新的PDF文档
            newDocument.save(tarPdfPath);
            //删除原文件
            deleteFile(srcPdfPath);
            log.info("PDF文件已成功另存为图像PDF: " + tarPdfPath);
            System.out.println("PDF文件已成功另存为图像PDF: " + tarPdfPath);
        } catch (IOException e) {
            log.error("无法加载或处理PDF文件: " , e);
        }
    }
    /**
     * @Description 删除没有用的文件
     * @Author yangxm
     * @Date 2023/5/12 10:51 AM
     * @Param [path]
     */
    public static boolean deleteFile(String path) {
        boolean result = false;
        File file = new File(path);
        if (file.isFile() && file.exists()) {
            int tryCount = 0;
            while (!result && tryCount++ < 10) {
                System.gc();
                result = file.delete();
            }
        }
        return result;
    }

    /**
     * @Description 创建文件及路径
     * @Author yangxm
     * @Date 2023/5/15 10:43 AM
     * @Param [filePath]
     */
    public static void createFilePath(String filePath) throws IOException {
        File file = new File(filePath);
        if (file.exists()) {
            return;
        }
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
    }
}
